player = {}

player.pos = { x=0,y=0,gx=0,gy=0 }
--Image to draw for the player
player.image = love.graphics.newImage('game/sub1.png')
--Whether or not the player should move in any direction

--Max speed the player can move
player.maxVel = 150
--Whether or not to flip the player image to match their direction
player.drawL = false
--Pings that the player can shoot out
pings = {}
player.firePing = love.sound.newSoundData('game/firePing.ogg')
pingFade = {}

--Missiles
player.missiles = {}
player.fireMissile = love.sound.newSoundData('game/fireMissile.ogg')
player.expMissile = love.sound.newSoundData('game/explodeMissile.ogg')
player.ping = love.sound.newSoundData('game/ping.ogg')
player.mi = love.graphics.newImage('game/missile.png')

function player:create()
  player.dead = false
  player.health = 3
  player.move = {u=false,d=false,l=false,r=false}
  
  player.canFire = true
  --Offset for drawing player
  player.iOff = {x= -grid*1.35*screen.scale, y = grid/2 - player.image:getHeight()/2 - (7*screen.scale) - grid}
  --Get the player's pixel position
  player.pos.x,player.pos.y = player.pos.gx*grid,player.pos.gy*grid
  --Create physics body
  player.body = love.physics.newBody(world, player.pos.x, player.pos.y, 'dynamic')
  player.body:setFixedRotation(true)
  player.body:setLinearDamping(0.1)
  player.shape = love.physics.newRectangleShape(0,-7.5*screen.scale,142.5*screen.scale, 54*screen.scale)
  player.fixture = love.physics.newFixture(player.body,player.shape)
  player.fixture:setRestitution(0.1)
  player.fixture:setCategory(1)
  
  --Player Vectors
  --Coorinates for vector drawing of the player
player.vectorR = {[1] = {x = 0, y = 0}, [2] = {x = 28, y = -15}, [3] = {x = 138, y = -15}, [4] = {x = 145, y = -4},
      [5] = {x = 145, y = 8}, [6] = {x = 138, y = 19}, [7] = {x = 28, y = 19}, [8] = {x = 5, y = -4}, [9] = {x = 5, y = -15},
      [10] = {x = 5, y = -15}, [11] = {x = 26, y = -15}, [12] = {x = 5, y = 4}, [13] = {x = 5, y = 19},
      [14] = {x = 5, y = 19}, [15] = {x = 27, y = 19}, [16] = {x = 80, y = -16}, [17] = {x = 100, y = -35},
      [18] = {x = 100, y = -35},[19] = {x = 125, y = -35}, [20] = {x = 125, y = -15}, [21] = {x = 125, y = -35}}
player.vectorL = {[1] = {x = 145, y = 0}, [2] = {x = 117, y= -15}, [3] = {x = 7, y = -15}, [4] = {x = 0, y = -4},
    [5] = {x = 0, y = 8}, [6] = {x = 7, y = 19}, [7] = {x = 117, y = 19}, [8] = {x = 140, y =-4}, [9] = {x = 140, y =-15},
    [10] = {x = 140, y = -15}, [11] = {x = 119, y = -15}, [12] = {x = 140, y = 4}, [13] = {x = 140, y = 19},
    [14] = {x = 140, y = 19}, [15] = {x = 118, y = 19}, [16] = {x = 65, y = -16}, [17] = {x = 45, y = -35},
    [18] = {x = 45, y = -35},[19] = {x = 20, y = -35}, [20] = {x = 20, y = -15}, [21] = {x = 20, y = -35}} 
  for i = 1, #player.vectorR, 1 do
    player.vectorR[i].x = player.vectorR[i].x*screen.scale
    player.vectorR[i].y = player.vectorR[i].y*screen.scale
  end

 for i = 1, #player.vectorL, 1 do
    player.vectorL[i].x = player.vectorL[i].x*screen.scale
    player.vectorL[i].y = player.vectorL[i].y*screen.scale
  end
end
--
function player:update(dt)
  --How is player's health?
  if player.health <= 0 then
    player.dead = true
  end
  
  player.pos.x = player.body:getX()
  player.pos.y = player.body:getY()
  --Clamp the player's grid position to the nearest grid space
  player.pos.gx = math.floor((player.pos.x+grid/2)/grid-1)
  player.pos.gy = math.floor((player.pos.y+grid/2)/grid - 1)
  
  --Acceleration
  if not player.dead then
  if player.move.u then
    player.body:applyForce(0,-1000)
  elseif player.move.d then
    player.body:applyForce(0,1000)
  end
  if player.move.l then
    player.body:applyForce(-1000,0)
  elseif player.move.r then
    player.body:applyForce(1000,0)
  end
  --Clamp the player's velocity to +- player.maxVel
  local vx,vy = player.body:getLinearVelocity()
  vx = math.min(math.max(-player.maxVel, vx), player.maxVel)
  vy = math.min(math.max(-player.maxVel, vy), player.maxVel)
  player.body:setLinearVelocity(vx,vy)
else
  player.body:applyForce(0,1000)
  end
  
  --Reload missiles
  if not player.canFire then
    if player.reload >= 3 then
      player.canFire = true
    end
    
    player.reload = player.reload + dt
  end
  
  
  --Update Pings
  for i = 1, #pings, 1 do
    local p = pings[i]
    --Countdown timer on ping fadeout
    p.timer = p.timer - 150*dt
    --Remove a ping if the timer has run out
    if p.timer <0 then
      table.remove(pings,i)
      return
    end
    
    --See if a ping has bounced off of something
    local px,py = p.body:getLinearVelocity()
    if (px >= 0 and p.px < 0) or (px <= 0 and p.px > 0) or (py >= 0 and p.py < 0) or (py <= 0 and p.py > 0) then
      --Store the location where it hit
      p.sound:setVolume((p.timer/255)*.4)
      love.audio.play(p.sound)
      local h = #pingFade + 1
      pingFade[h] = {}
      pingFade[h].x,pingFade[h].y = p.body:getPosition()
      --Time to handle fading it of darkness
      pingFade[h].timer = 0
    end
    --Update previous velocity
    p.px,p.py = px,py
  end
  
  --Update pingfade
  for i = 1, #pingFade, 1 do
    pingFade[i].timer = pingFade[i].timer + 450*dt
    if pingFade[i].timer > 255 then
      table.remove(pingFade,i)
      return
    end
  end
  
  --Update missiles
  for i = 1, #player.missiles, 1 do
    player.missiles[i].anim:update(dt)
    local x,y = player.missiles[i].body:getLinearVelocity()
    --If the velocity of the missile has changed, explode.
    if (x ~= player.missiles[i].px or y ~= player.missiles[i].py) and not player.missiles[i].drawExp then
      player.missiles[i].ex, player.missiles[i].ey = player.missiles[i].body:getPosition()
      player.missiles[i].drawExp = true
      player.missiles[i].anim:gotoFrame(1)
      player.missiles[i].anim:resume()
      player.missiles[i].timer = 0
      --Remove physics fixture from missile so it can't collide a second time
      player.missiles[i].fixture:destroy()
    end
    
    if player.missiles[i].drawExp then
      player.missiles[i].timer = player.missiles[i].timer + dt
      if player.missiles[i].timer >= 1 then
        table.remove(player.missiles[i])
      end
    end
    
  end
  
end
--
function player:draw()
  love.graphics.setLineWidth(1)

  --Draw the player's sub
  love.graphics.setColor(0,255,0,255)
  if player.drawL then
    --love.graphics.draw(player.image, player.pos.x - player.iOff.x - grid, player.pos.y + player.iOff.y,0,-1,1)
    drawPlayer('left')
  else
    --love.graphics.draw(player.image, player.pos.x + player.iOff.x, player.pos.y + player.iOff.y,0,1,1)
    drawPlayer('right')
  end
  
  --Draw pings
  --Ball
  for i = 1, #pings, 1 do
    local p = pings[i]
    --Have the ping ball fade out over time
    love.graphics.setColor(255,255,255,p.timer)
    love.graphics.circle("fill", p.body:getX() - grid/2,p.body:getY() - grid/2, p.shape:getRadius())
  end
  
  --PingFades
  love.graphics.setLineWidth(1)
  for i = 1, #pingFade, 1 do
    if pingFade[i].timer >= 55 then
    love.graphics.setColor(0,0,0,255)
    love.graphics.circle('line',pingFade[i].x-64,pingFade[i].y-64,64*((pingFade[i].timer-50)/255))
  end
   if pingFade[i].timer >= 105 then
    love.graphics.circle('line',pingFade[i].x-64,pingFade[i].y-64,64*((pingFade[i].timer-100)/255))
    end
    if pingFade[i].timer >= 155 then
    love.graphics.circle('line',pingFade[i].x-64,pingFade[i].y-64,64*((pingFade[i].timer-150)/255))
    end
  end
  
  --Missiles
  for i = 1, #player.missiles, 1 do
    if not player.missiles[i].drawExp then
    love.graphics.setColor(255,255,0,255)
    love.graphics.draw(player.mi, player.missiles[i].body:getX() - grid/2, player.missiles[i].body:getY() - grid/2, player.missiles[i].body:getAngle(),0.5,1)
    else
      love.graphics.setColor(255,128,0,255)
      player.missiles[i].anim:draw(explosion.i, player.missiles[i].ex - (explosion.i:getWidth()/6*2)*screen.scale, player.missiles[i].ey - (explosion.i:getHeight()*2)*screen.scale)
    end
    
  end
  
  
end
--
--
--Key pressed
function player:kp(k)
  if k == 'w' or k == 'up' then
    player.move.u = true
  elseif k == 's' or k == 'down' then
    player.move.d = true
  end
  if k == 'a' or k == 'left' then
    player.move.l = true
    player.drawL = true
  elseif k == 'd'  or k == 'right' then
    player.move.r = true
    player.drawL = false
  end 
  
end
--Key released
function player:kr(k)
  if k == 'w' or k == 'up' then
    player.move.u = false
  elseif k == 's' or k == 'down' then
    player.move.d = false
  end
  if k == 'a' or k == 'left' then
    player.move.l = false
  elseif k == 'd' or k == 'right' then
    player.move.r = false
  end 
end
--Mouse pressed
function player:mp(x,y,b)
  --Returns mouse position with respect to camera translation
    local x,y = camera:mousepos()
    local angle = math.atan2(y - player.pos.y + grid/2, x - player.pos.x + grid/2)
  if b == 'l' then
    --Limit of 5 pings at a time
    if #pings < 5 then
    local p = #pings + 1
    pings[p] = {}
    pings[p].body = love.physics.newBody(world, player.pos.x,player.pos.y, 'dynamic')
    pings[p].shape = love.physics.newCircleShape(2)
    pings[p].fixture = love.physics.newFixture(pings[p].body,pings[p].shape, 0.05)
    pings[p].fixture:setRestitution(1)
    pings[p].fixture:setCategory(2)
    pings[p].fixture:setMask(1)
    pings[p].body:applyLinearImpulse(math.cos(angle)*2,math.sin(angle)*2)
    pings[p].timer = 255
    --Used to hold a ping's velocity from the previous frame
    pings[p].px = 0
    pings[p].py = 0
    pings[p].sound = love.audio.newSource(player.ping, 'static')
    pings[p].fire = love.audio.newSource(player.firePing, 'static')
    pings[p].fire:setVolume(0.5)
    love.audio.play(pings[p].fire)
    end
  elseif b == 'r' then
    if player.canFire then
      local m = player.missiles
      local i = #m + 1
      m[i] = {}
      m[i].body = love.physics.newBody(world, player.pos.x,player.pos.y, 'dynamic')
      m[i].shape = love.physics.newRectangleShape(0,0,10,1)
      m[i].fixture = love.physics.newFixture(m[i].body,m[i].shape)
      m[i].body:setAngle(angle)
      m[i].body:setLinearDamping(0)
      m[i].fixture:setRestitution(0)
      m[i].fixture:setCategory(6)
      m[i].fixture:setMask(1,2)
      m[i].body:applyLinearImpulse(math.cos(angle)*20,math.sin(angle)*20)
      local g = anim8.newGrid(64,64, explosion.i:getWidth(), explosion.i:getHeight())
      m[i].anim = anim8.newAnimation(g('1-6',1), 0.05, 'pauseAtEnd')
      m[i].drawExp = false
      m[i].px, m[i].py = m[i].body:getLinearVelocity()
      m[i].ex, m[i].ey = 0,0
      m[i].fire = love.audio.newSource(player.fireMissile, 'static')
      m[i].fire:setVolume(0.3)
      m[i].explode = love.audio.newSource(player.expMissile, 'static')
      love.audio.play(m[i].fire)
      
      player.reload = 0
      player.canFire = false
    end
  end
  
end
--Mouse released
function player:mr(x,y,b)
end
--
--
function drawPlayer(dir)
  local x,y = player.pos.x, player.pos.y
  local sx,sy = x-grid*.9, y-grid/2
  if dir == 'right' then
    for i = 1, #player.vectorR, 1 do
      --Draw the sub body
      if i <= 6 then
        local r1 = player.vectorR[i]
        local r2 = player.vectorR[i+1]
        love.graphics.line(sx + r1.x, sy + r1.y, sx + r2.x, sy + r2.y)
        if i == 6 then
          love.graphics.line(sx + r2.x, sy + r2.y, sx + player.vectorR[1].x, sy + player.vectorR[1].y)
        end
      else
        --Draw fins and hatch
        if i%2 == 0 then
          local r1 = player.vectorR[i]
          local r2 = player.vectorR[i+1]
          love.graphics.line(sx+r1.x,sy+r1.y, sx+r2.x, sy+r2.y)
        end
      end
    end
  else
    for i = 1, #player.vectorL, 1 do
      --Draw the sub body
      if i <= 6 then
        local r1 = player.vectorL[i]
        local r2 = player.vectorL[i+1]
        love.graphics.line(sx + r1.x, sy + r1.y, sx + r2.x, sy + r2.y)
        if i == 6 then
          love.graphics.line(sx + r2.x, sy + r2.y, sx + player.vectorL[1].x, sy + player.vectorL[1].y)
        end
      else
        --Draw fins and hatch
        if i%2 == 0 then
          local r1 = player.vectorL[i]
          local r2 = player.vectorL[i+1]
          love.graphics.line(sx+r1.x,sy+r1.y, sx+r2.x, sy+r2.y)
        end
      end
    end
  end

end

